/*    Copyright 2010 Tobias Marschall
 *
 *    This file is part of MoSDi.
 *
 *    MoSDi is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    MoSDi is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with MoSDi.  If not, see <http://www.gnu.org/licenses/>.
 */

package mosdi.tests;

import static org.junit.Assert.*;

import java.io.File;
import java.util.Random;

import mosdi.distributions.InhomogeneousDistribution;
import mosdi.util.BitArray;

import org.junit.Test;

public class InhomogeneousDistributionTest {

   @Test
   public void testReadFromAndWriteToFile() {
      File testFile = new File("testFile"+System.currentTimeMillis());
      if (testFile.exists()) {
         System.err.printf("Sorry, the file '%s' already exists.%n Abort test.", testFile);
         return;
      }
      
      BitArray[] bitArrays = new BitArray[5];
      for (int i = 0; i < bitArrays.length; ++i) {
         bitArrays[i] = new BitArray(4);
         bitArrays[i].set(0, true);
         bitArrays[i].set(1, true);
         bitArrays[i].set(2, true);
         bitArrays[i].set(3, true);
      }
      bitArrays[0].set(0, false);
      bitArrays[1].set(1, false);
      bitArrays[2].set(2, false);
      bitArrays[3].set(3, false);
      bitArrays[4].set(1, false);
      bitArrays[4].set(3, false);

      InhomogeneousDistribution id = new InhomogeneousDistribution(27,new double[]{0.25,0.25,0.25,0.25});
      int[] mapToRestriction = {-1,0,-1,-1,1,0,1-1,-1,0,0,2,3,1,-1,4,4,-1-1,3,3,3,2,1,2,4,-1};
      for (int i = 0; i < mapToRestriction.length; ++i) {
         if (mapToRestriction[i] >= 0) {
            id.restrictDistribution(i, bitArrays[mapToRestriction[i]]);
         }
      }
      id.writeToFile(testFile);
      InhomogeneousDistribution testID = InhomogeneousDistribution.readFromFile(testFile.getPath());
      assertArrayEquals(id.getPositionArray(),testID.getPositionArray());
      for (int pos = 0; pos < 27; ++pos) {
         assertArrayEquals(id.getDistribution(pos), testID.getDistribution(pos), 0.00000001);
      }
      for (int idx = 0; idx < 6; ++idx) {
         assertArrayEquals(id.getDistributionByIndex(idx), testID.getDistributionByIndex(idx), 0.00000001);
      }
      testFile.delete();
      
      id = new InhomogeneousDistribution(10000 ,new double[]{0.25,0.25,0.25,0.25});
      id.writeToFile(testFile);testID = InhomogeneousDistribution.readFromFile(testFile.getPath());
      assertArrayEquals(id.getPositionArray(),testID.getPositionArray());
      for (int pos = 0; pos < 10000; ++pos) {
         assertArrayEquals(id.getDistribution(pos), testID.getDistribution(pos), 0.00000001); 
      }
      for (int idx = 0; idx < 0; ++idx) {
         assertArrayEquals(id.getDistributionByIndex(idx), testID.getDistributionByIndex(idx), 0.00000001);
      }
      testFile.delete();
      
      Random rand = new Random(5);
      mapToRestriction = new int[10000];
      for (int i = 0; i < mapToRestriction.length; ++i) {
         mapToRestriction[i] = rand.nextInt(6)-1;
      }
      for (int i = 0; i < mapToRestriction.length; ++i) {
         if (mapToRestriction[i] >= 0) {
            id.restrictDistribution(i, bitArrays[mapToRestriction[i]]);
         }
      }
      id.writeToFile(testFile);testID = InhomogeneousDistribution.readFromFile(testFile.getPath());
      assertArrayEquals(id.getPositionArray(),testID.getPositionArray());
      for (int pos = 0; pos < 10000; ++pos) {
         assertArrayEquals(id.getDistribution(pos), testID.getDistribution(pos), 0.00000001); 
      }
      for (int idx = 0; idx < 6; ++idx) {
         assertArrayEquals(id.getDistributionByIndex(idx), testID.getDistributionByIndex(idx), 0.00000001);
      }
      testFile.delete();
      
   }
}
